package com.tyylab.kestrel.framework.core.util;

import net.bytebuddy.description.type.TypeDescription;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.ArrayList;
import java.util.List;

/**
 * 用于将 Java 反射中的 ParameterizedType 转换为 ByteBuddy 的 Generic 类型
 *
 * @author tyylab
 */
public class GenericConverter {

    /**
     * 将 ParameterizedType 转换为 ByteBuddy 的 Generic 类型
     *
     * @param parameterizedType 要转换的 ParameterizedType
     * @return 对应的 ByteBuddy Generic 类型
     */
    public static TypeDescription.Generic convert(ParameterizedType parameterizedType) {
        if (parameterizedType == null) {
            return null;
        }

        // 获取原始类型
        Type rawType = parameterizedType.getRawType();
        TypeDescription rawTypeDescription = TypeDescription.ForLoadedType.of((Class<?>) rawType);

        // 获取类型参数
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        List<TypeDescription.Generic> typeArguments = new ArrayList<>();

        for (Type typeArgument : actualTypeArguments) {
            TypeDescription.Generic genericTypeArgument = convertType(typeArgument);
            typeArguments.add(genericTypeArgument);
        }

        // 创建参数化类型
        return TypeDescription.Generic.Builder.parameterizedType(rawTypeDescription, typeArguments).build();
    }

    /**
     * 将任意 Type 转换为 ByteBuddy 的 Generic 类型
     *
     * @param type 要转换的 Type
     * @return 对应的 ByteBuddy Generic 类型
     */
    private static TypeDescription.Generic convertType(Type type) {
        if (type == null) {
            return null;
        }

        if (type instanceof Class) {
            // 普通类
            Class<?> clazz = (Class<?>) type;
            return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(clazz);
        } else if (type instanceof ParameterizedType) {
            // 参数化类型
            return convert((ParameterizedType) type);
        } else if (type instanceof TypeVariable) {
            // 类型变量 - 简化为 Object 类型
            return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class);
        } else if (type instanceof WildcardType) {
            // 通配符类型 - 简化为 Object 类型
            return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class);
        } else {
            // 其他类型，尝试作为普通类处理
            try {
                Class<?> clazz = (Class<?>) type;
                return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(clazz);
            } catch (ClassCastException e) {
                // 如果无法转换，返回 Object 类型
                return TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(Object.class);
            }
        }
    }

    /**
     * 批量转换多个 ParameterizedType
     *
     * @param parameterizedTypes 要转换的 ParameterizedType 数组
     * @return 对应的 ByteBuddy Generic 类型列表
     */
    public static List<TypeDescription.Generic> convertAll(ParameterizedType... parameterizedTypes) {
        List<TypeDescription.Generic> result = new ArrayList<>();
        for (ParameterizedType parameterizedType : parameterizedTypes) {
            result.add(convert(parameterizedType));
        }
        return result;
    }

    /**
     * 检查给定的 Type 是否为 ParameterizedType
     *
     * @param type 要检查的 Type
     * @return 如果是 ParameterizedType 返回 true，否则返回 false
     */
    public static boolean isParameterizedType(Type type) {
        return type instanceof ParameterizedType;
    }

    /**
     * 安全地转换 Type 为 ParameterizedType
     *
     * @param type 要转换的 Type
     * @return 如果是 ParameterizedType 则返回，否则返回 null
     */
    public static ParameterizedType safeCastToParameterizedType(Type type) {
        return isParameterizedType(type) ? (ParameterizedType) type : null;
    }
}
